// +build windows

/**
* @Author: zou.yingbin
* @Create  : 2020/9/25 13:37
* @Modify  : 2020/9/25 13:37
 */

package main

import (
	"fmt"
	"github.com/lxn/walk"
	. "github.com/lxn/walk/declarative"
	"math"
	"strconv"
	"time"
)

// 字段转换,参数 值,新值,值2,新值2...
func CovertField(src string, args ...string) string {
	for i := 0; i < len(args); i = i + 2 {
		if src == args[i] {
			return args[i+1]
		}
	}

	return src
}

// 去掉价格后面多余的0
func truncPriceZero(strPrice string) string {
	if len(strPrice) > 3 {
		for i := len(strPrice) - 1; i > 2; i-- {
			if strPrice[i] == '0' {
				continue
			}

			if strPrice[i] == '.' {
				return strPrice[0:i]
			} else {
				return strPrice[0 : i+1]
			}
		}
	}

	return strPrice
}

type stQuote struct {
	GoodsCode string
	GoodsName string
	BidPrice  float64
	AskPrice  float64
	LastPrice float64
	MarketId  uint32
	Tm        string
}

type stQuoteModel struct {
	walk.TableModelBase
	items []*stQuote
}

func (r *stQuoteModel) Items() interface{} {
	return r.items
}

func (r *stQuoteModel) SetGoods() {
	r.items = make([]*stQuote, 0, 200)
	/*for i := 0; i < 100; i++ {
		r.items = append(r.items, &stQuote{GoodsCode: "GC2010", BidPrice: 1925.2, AskPrice: 1924.3, LastPrice: 1900})
	}*/

	for _, s := range usrConn {
		if s.bLogin && len(s.goodsMap) > 0 {
			for _, goods := range s.goodsMap {
				val := new(stQuote)
				val.GoodsCode = goods.goodsCode
				val.GoodsName = goods.goodsName
				val.MarketId = goods.marketId

				var decimal float64 = 0
				if g, ok := s.goodsMap[goods.goodsCode]; ok {
					decimal = float64(g.decimal)
				}

				if q, ok := s.quote.mQuote[goods.goodsCode]; ok {
					val.AskPrice = q.AskPrice / math.Pow(10, decimal)
					val.BidPrice = q.BidPrice / math.Pow(10, decimal)
					val.LastPrice = q.LastPrice / math.Pow(10, decimal)
					if len(q.Tm) == 6 {
						val.Tm = q.Tm[0:2] + ":" + q.Tm[2:4] + ":" + q.Tm[4:]
						//fmt.Printf("%+v\n", val)
					} else {
						val.Tm = q.Tm
					}
				}

				r.items = append(r.items, val)
			}
			break
		}
	}

	//fmt.Println("---update goods tableView---", len(r.items))
	r.PublishRowsReset()
}

func NewQuoteModel() *stQuoteModel {
	m := new(stQuoteModel)
	m.SetGoods()
	return m
}

type stPosModel struct {
	walk.TableModelBase
	items  []stPosition
	strAcc string
}

func (r *stPosModel) Items() interface{} {
	return r.items
}

func (r *stPosModel) SetData(strAcc string) bool {

	if len(strAcc) == 0 {
		return false
	}
	r.strAcc = strAcc
	if s := GetSession(strAcc); s != nil {
		s.qryPosition()

		for i := 0; i < 6; i++ {
			if s.bRecvPos {
				break
			}

			time.Sleep(time.Millisecond * 500)
		}

		if len(s.position) > 0 {
			r.items = make([]stPosition, len(s.position))
			copy(r.items, s.position)
			for i, item := range r.items {
				if item.BuyOrSell == "0" {
					r.items[i].BuyOrSell = "买入"
				} else {
					r.items[i].BuyOrSell = "卖出"
				}
			}

			r.PublishRowsReset()

			return true
		} else {
			r.items = make([]stPosition, 0)
			return true
		}
	}

	return false
}

type stOrderModel struct {
	walk.TableModelBase
	items  []stOrder
	strAcc string
}

func (r *stOrderModel) Items() interface{} {
	return r.items
}

func (r *stOrderModel) SetData(strAcc string) bool {
	if len(strAcc) == 0 {
		return false
	}
	r.strAcc = strAcc
	if s := GetSession(strAcc); s != nil {
		s.qryOrder()

		for i := 0; i < 6; i++ {
			if s.bRecvOrder {
				break
			}

			time.Sleep(time.Millisecond * 500)
		}

		if len(s.orders) > 0 {
			r.items = make([]stOrder, len(s.orders))
			copy(r.items, s.orders)
			for i, item := range r.items {
				r.items[i].BuyOrSell = CovertField(item.BuyOrSell, "0", "买入", "1", "卖出")
				r.items[i].BuildType = CovertField(item.BuildType, "1", "建仓", "2", "平仓", "3", "自动开平")
				r.items[i].OrderStatus = CovertField(item.OrderStatus, "1", "委托请求",
					"2", "冻结成功", "3", "委托失败", "5", "委托成功", "6", "全部撤销", "7", "部成部撤", "9", "全部成交")
				if len(r.items[i].OrderTime) > 8 {
					// 去掉时间最后的".0"
					r.items[i].OrderTime = r.items[i].OrderTime[0 : len(r.items[i].OrderTime)-2]
				}

				// 去掉价格后面多余的0
				r.items[i].OrderPrice = truncPriceZero(item.OrderPrice)
			}

			r.PublishRowsReset()

			return true
		} else {
			r.items = make([]stOrder, 0)
			return true
		}
	}

	return false
}

func OrderDlg(f OrderHandle) {
	valOrder := &stOrderUI{
		Qty:       1,
		BuyOrSell: 0,
		BuildType: 1,
		MarketID:  15201,
	}

	var mw *walk.MainWindow
	var db *walk.DataBinder
	var tb *walk.TableView
	var le *walk.LineEdit
	var leM *walk.NumberEdit
	tbModel := NewQuoteModel()

	var tbvPos *walk.TableView
	tbvPosModel := new(stPosModel)

	var tbvOrder *walk.TableView
	tbvOrderModel := new(stOrderModel)

	uiGoodsTable := func() TableView {
		return TableView{
			AssignTo:      &tb,
			Name:          "tableView",
			StretchFactor: 2,
			StyleCell: func(style *walk.CellStyle) {
				style.BackgroundColor = walk.RGB(255, 232, 203)
			},
			Model: tbModel,
			OnCurrentIndexChanged: func() {
				if index := tb.CurrentIndex(); index > -1 {
					goodsCode := tbModel.items[index].GoodsCode
					_ = le.SetText(goodsCode)
					valOrder.GoodsCode = goodsCode
					valOrder.MarketID = tbModel.items[index].MarketId
					_ = db.Reset()
				}
			},
			Columns: []TableViewColumn{
				{Title: "商品名称", DataMember: "GoodsName", Width: 120},
				{Title: "商品代码", DataMember: "GoodsCode", Width: 60},
				{Title: "买价", DataMember: "BidPrice", Format: "%g", Alignment: AlignDefault, Width: 60},
				{Title: "卖价", DataMember: "AskPrice", Format: "%g", Width: 60},
				{Title: "最新价", DataMember: "LastPrice", Format: "%g", Width: 60},
				{Title: "时间", DataMember: "Tm", Width: 60},
			},
		}
	}

	// 下单面板
	uiOrderPanel := func() Composite {
		return Composite{
			Layout: Grid{Columns: 2},
			Children: []Widget{
				Label{Text: "登录账号:"},
				LineEdit{Text: Bind("LoginId"), ToolTipText: "登录ID用逗号隔开;\n可不填,表示所有账户都下单"},
				Label{Text: "市 场ID:"},
				NumberEdit{Value: Bind("MarketID"), AssignTo: &leM, Decimals: 0},
				Label{Text: "商品代码:"},
				LineEdit{Text: Bind("GoodsCode"), AssignTo: &le},
				Label{Text: "委托数量:"},
				NumberEdit{Value: Bind("Qty", Range{Min: 1, Max: 99999}), Decimals: 0},
				Label{Text: "委托价格:"},
				NumberEdit{Value: Bind("OrderPrice"), Decimals: 2},

				RadioButtonGroupBox{ColumnSpan: 2, Title: "buyOrSell", Layout: HBox{}, DataMember: "BuyOrSell",
					Buttons: []RadioButton{
						{Text: "买入", Value: uint32(0)},
						{Text: "卖出", Value: uint32(1)},
					},
				},
				RadioButtonGroupBox{ColumnSpan: 2, Title: "buildType", Layout: Grid{Columns: 3}, DataMember: "BuildType",
					Buttons: []RadioButton{
						{Text: "开仓", Value: uint32(1), MaxSize: Size{Width: 50, Height: 0}},
						{Text: "平仓", Value: uint32(2), MaxSize: Size{Width: 50, Height: 0}},
						{Text: "自动开平", Value: uint32(3), MaxSize: Size{Width: 80, Height: 0}},
					},
				},
				Label{Text: "关联单号:"},
				LineEdit{Text: Bind("RelateIDTxt"), Enabled: false},
				Label{Text: "ps:在委托单列表中选择关联单号进行撤单", ColumnSpan: 2},
				Composite{
					ColumnSpan: 2,
					Layout:     HBox{},
					Children: []Widget{
						PushButton{Text: "<-刷新", MaxSize: Size{Width: 50},
							OnClicked: func() {
								tbModel.SetGoods()
								_ = tb.SetModel(tbModel)
								tbModel.PublishRowsReset()
							},
						},
						PushButton{Text: "撤单", MaxSize: Size{Width: 45},
							OnClicked: func() {
								if err := db.Submit(); err == nil {
									if len(valOrder.RelateIDTxt) < 2 {
										walk.MsgBox(mw, "提示", "请选择要撤单的委托单", walk.MsgBoxOK)
										return
									}

									if s := GetSession(tbvOrderModel.strAcc); s != nil {
										orderId, _ := strconv.ParseUint(valOrder.RelateIDTxt, 10, 64)
										s.SendCancelOrder(orderId)
									}
								}
							}},
						PushButton{Text: "斩仓", MaxSize: Size{Width: 45},
							OnClicked: func() {
								if err := db.Submit(); err == nil {

									if len(valOrder.GoodsCode) < 2 {
										walk.MsgBox(mw, "提示", "请输入商品代码", walk.MsgBoxOK)
										return
									}

									if len(valOrder.LoginId) < 2 {
										walk.MsgBox(mw, "提示", "请输入登录ID", walk.MsgBoxOK)
										return
									}

									if s := GetSession(valOrder.LoginId); s != nil {
										s.SendRiskCloseReq(valOrder)
									}
								}
							},
						},
						PushButton{Text: "下单", MaxSize: Size{Width: 50},
							OnClicked: func() {
								if err := db.Submit(); err == nil {
									if len(valOrder.GoodsCode) < 2 {
										walk.MsgBox(mw, "提示", "请输入商品代码", walk.MsgBoxOK)
										return
									} else if valOrder.Qty == 0 {
										walk.MsgBox(mw, "提示", "请输入委托数量", walk.MsgBoxOK)
										return
									}

									f(valOrder)
								}
							},
						},
					},
				},
			},
		}
	}

	// 账户操作面板
	var leAcc *walk.LineEdit
	uiAccOp := Composite{
		Layout: HBox{Margins: Margins{Top: 0, Left: 6, Right: 6, Bottom: 2}},
		Children: []Widget{
			Label{Text: "登录账户:"},
			LineEdit{Text: "2100000003", AssignTo: &leAcc, MaxSize: Size{Width: 100, Height: 0}},
			PushButton{Text: "查资金"},
			PushButton{Text: "查持仓", OnClicked: func() {
				if tbvPosModel.SetData(leAcc.Text()) {
					_ = tbvPos.SetModel(tbvPosModel)
					tbvPosModel.PublishRowsReset()
				}
			}},
			PushButton{Text: "查委托", OnClicked: func() {
				if tbvOrderModel.SetData(leAcc.Text()) {
					_ = tbvOrder.SetModel(tbvOrderModel)
					tbvOrderModel.PublishRowsReset()
				}
			}},
		},
	}
	/*
		uiFundTable := TableView{
			Name: "资金",
			Columns: []TableViewColumn{
				TableViewColumn{Title: "账户ID", DataMember: "GoodsName", Width: 120},
				TableViewColumn{Title: "可用资金", DataMember: "GoodsCode", Width: 60},
				TableViewColumn{Title: "占用资金", DataMember: "BidPrice", Format: "%g", Alignment: AlignDefault, Width: 60},
				TableViewColumn{Title: "当前余额", DataMember: "AskPrice", Format: "%g", Width: 60},
				TableViewColumn{Title: "冻结资金", DataMember: "LastPrice", Format: "%g", Width: 60},
			},
		}
	*/

	// 持仓汇总表
	uiPositionTable := TableView{
		StretchFactor: 10,
		AssignTo:      &tbvPos,
		Model:         tbvPosModel,
		Name:          "持仓汇总",
		Columns: []TableViewColumn{
			{Title: "商品", DataMember: "GoodsCode", Width: 80},
			{Title: "买/卖", DataMember: "BuyOrSell", Width: 80},
			{Title: "持有总量", DataMember: "CurQty", Width: 80},
			{Title: "冻结数量", DataMember: "FrozenQty", Width: 80},
		},
	}

	// 委托明细表
	uiOrderTable := TableView{
		StretchFactor: 20,
		AssignTo:      &tbvOrder,
		Model:         tbvOrderModel,
		Name:          "委托明细",
		Columns: []TableViewColumn{
			{Title: "委托时间", DataMember: "OrderTime", Width: 120},
			{Title: "单号", DataMember: "OrderId", Width: 130},
			{Title: "商品", DataMember: "GoodsCode", Width: 60},
			{Title: "买/卖", DataMember: "BuyOrSell", Width: 60},
			{Title: "开平", DataMember: "BuildType", Width: 60},
			{Title: "委托价格", DataMember: "OrderPrice", Width: 70},
			{Title: "委托数量", DataMember: "OrderQty", Width: 60},
			{Title: "状态", DataMember: "OrderStatus", Width: 60},
		},
		ToolTipText: "选中可撤委托单,自动填充到下单界面的关联委托单框",
		OnCurrentIndexChanged: func() {
			if index := tbvOrder.CurrentIndex(); index > -1 {
				orderId := tbvOrderModel.items[index].OrderId
				valOrder.RelateID, _ = strconv.ParseUint(orderId, 10, 64)
				valOrder.RelateIDTxt = orderId
				_ = db.Reset()
			}
		},
	}

	// 主窗口
	if _, err := (MainWindow{
		AssignTo: &mw,
		Title:    "下单窗口(所有操作结果请关注命令行窗口的信息)",
		Size:     Size{Width: 720, Height: 650},
		MinSize:  Size{Width: 720, Height: 650},
		Layout:   VBox{},
		DataBinder: DataBinder{
			AssignTo:       &db,
			Name:           "stOrderUI",
			DataSource:     valOrder,
			ErrorPresenter: ToolTipErrorPresenter{},
		},
		Children: []Widget{
			GroupBox{Title: "账户面板", Layout: VBox{},
				StretchFactor: 50,
				Children: []Widget{
					uiAccOp,
					//Label{Text: "持仓汇总:"},
					uiPositionTable,
					//Label{Text: "委托单:"},
					uiOrderTable,
				},
			},
			HSplitter{
				Children: []Widget{
					uiGoodsTable(),
					uiOrderPanel(),
				},
			},
		},
	}.Run()); err != nil {
		fmt.Println(err)
	}
}
